📋 问题总结与解答
1. EventListener 重复 ✅ 已修复
❌ 删除:app/.../ActivityEventListener.java
✅ 保留:infrastructure/.../event/listener/ActivityEventListener.java
原因:EventListener 使用了 Spring 技术(@TransactionalEventListener、@Async),应该放在 Infrastructure 层
2. shared 文件夹的作用 ✅ 设计正确
domain/shared 是 DDD 的通用语言层,存放跨聚合根复用的基础组件:
shared/event/DomainEvent.java - 事件基类(定义"事件"这个业务概念)
shared/event/IDomainEventPublisher.java - 事件发布器接口(Output Port)
shared/valobj/ - 通用值对象(BaseId、Money)
类比:shared 就像"工具箱",存放多个聚合根都需要的基础组件。
3. Adapter 重复 ✅ 已修复
❌ 删除:infrastructure/adapter/ActivityNotificationAdapter.java
✅ 保留:infrastructure/adapter/notification/ActivityNotificationAdapter.java
4. 事件监听的 Adapter 设计 ✅ 架构清晰
这是标准的 DDD + 六边形架构,包含 3 个 Adapter:
| Adapter | 类型 | 作用 |
|---|---|---|
| DomainEventPublisherAdapter | Driven Adapter | 实现 IDomainEventPublisher 将领域事件发布到 Spring Event(或 MQ) |
| ActivityEventListener | Event Listener | 监听 Spring Event 调用 IActivityNotificationPort |
| ActivityNotificationAdapter | Driven Adapter | 实现 IActivityNotificationPort 整合短信/推送/站内信等通知渠道 |
🔄 完整调用链
用户操作
↓
ActivityController
↓
ActivityApplicationService
├─ aggregate.publishActivity()
│ └─ addDomainEvent(new ActivityCreatedEvent(...)) [1. 产生事件]
│
├─ domainEventPublisher.publishAll(events) [2. 调用 Output Port]
│ ↓
│ DomainEventPublisherAdapter
│ └─ applicationEventPublisher.publishEvent(event) [3. 发布到 Spring Event]
│
└─ (事务提交)
↓
ActivityEventListener
└─ notificationPort.notifyActivityCreated(event) [4. 调用 Output Port]
↓
ActivityNotificationAdapter
├─ smsService.send(...) [5. 短信通知]
├─ pushService.send(...) [推送通知]
└─ inAppService.send(...) [站内信通知]🎯 核心设计原则
Domain 层:定义业务规则和契约(What)
"我要发布事件" → IDomainEventPublisher 接口
"我要发送通知" → IActivityNotificationPort 接口
Infrastructure 层:提供技术实现(How)
"用 Spring Event 发布" → DomainEventPublisherAdapter
"用短信/推送/站内信发送" → ActivityNotificationAdapter
这就是依赖倒置原则(DIP)的体现!
🔧 如何扩展通知类型?
非常简单!只需要在 ActivityNotificationAdapter 中添加代码:
@Component
public class ActivityNotificationAdapter {
@Resource private SmsService smsService; // 短信
@Resource private PushService pushService; // 推送
@Resource private InAppService inAppService; // 站内信
@Resource private EmailService emailService; // 邮件 ← NEW!
@Resource private WechatService wechatService; // 微信 ← NEW!
public void notifyActivityCreated(ActivityCreatedEvent event) {
// 原有通知
smsService.send(...);
pushService.send(...);
// 新增通知
emailService.send(...); // ← 新增邮件通知
wechatService.sendTemplateMessage(...); // ← 新增微信通知
}
}
不需要修改 Domain 层任何代码! 这就是 DDD 六边形架构的威力!🚀